﻿using StarPizza.Model;
using StarPizza.Model.BaseModel;
using StarPizza.Model.Core;
using StarPizza.Model.Ordering;
using StarPizza.Model.User;
using StarPizza.ViewModel.ChefSystem;
using StarPizza.ViewModel.ClientSystem;
using StarPizza.ViewModel.Core;
using StarPizza.ViewModel.ManagerSystem;
using StarPizza.ViewModel.User;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace StarPizza.ViewModel
{
    class Shell
    {
        private ModelMain theModel;

        #region User
        UserAuthenticator theUserAuthenticator;
        public UserAuthenticator UserAuthenticator { get { return theUserAuthenticator; } }
        private void InitializeUserSystem(UserSpace userSpace)
        {
            theUserAuthenticator = new UserAuthenticator(userSpace);
        }
        #endregion

        #region Core
        ToppingLister theToppingLister;
        PizzaTemplateLister thePizzaTemplateLister;
        PizzaComposer thePizzaComposer;
        DoughLister theDoughLister;
        private void InitializeCore(StarDataDataContext db, IUserModeManager userModeManager, IIngredientResource ingredientResource, Catalogue catalogue)
        {
            theToppingLister = new ToppingLister(ingredientResource, userModeManager);
            thePizzaTemplateLister = new PizzaTemplateLister(catalogue);
            thePizzaComposer = new PizzaComposer(ingredientResource, theToppingLister);
            theDoughLister = new DoughLister(ingredientResource, userModeManager);
        }
        #endregion

        #region Client
        ClientRegistrator theClientRegistrator;
        ClientDataEditor theClientDataEditor;
        Cart theCart;
        PizzaSelector thePizzaSelector;
        CustomPizzaOrderer theCustomPizzaOrderer;
        OrderController theOrderController;
        ClientSystemVM theClientSystemVM;
        public ClientRegistrator ClientRegistrator { get { return theClientRegistrator; } }
        public ClientDataEditor ClientDataEditor { get { return theClientDataEditor; } }
        public ClientSystemVM ClientSystemVM { get { return theClientSystemVM; } }
        private void InitializeClientSystem(
            StarDataDataContext db, UserSpace userSpace,
            OrderProcessor orderProcessor, Catalogue catalogue, PizzaComposer pizzaComposer, DoughLister doughLister)
        {
            theOrderController = new OrderController(orderProcessor);
            theClientRegistrator = new ClientRegistrator(userSpace);
            theClientDataEditor = new ClientDataEditor(db, userSpace);
            thePizzaSelector = new PizzaSelector(catalogue, theOrderController, theDoughLister);
            theCustomPizzaOrderer = new CustomPizzaOrderer(pizzaComposer, theOrderController, theDoughLister);

            theCart = new Cart(theOrderController);
            theOrderController.setCart(theCart);

            theClientSystemVM = new ClientSystemVM(userSpace, theClientDataEditor, 
                doughLister, thePizzaSelector, theCustomPizzaOrderer, theCart);
        }
        #endregion

        #region Chef
        ChefPizzaCreator theChefPizzaCreator;
        ChefSystemVM theChefSystemVM;
        public ChefSystemVM ChefSystemVM { get { return theChefSystemVM; } }
        private void InitializeChefSystem(Catalogue catalogue, UserSpace userSpace, PizzaComposer pizzaComposer)
        {
            theChefPizzaCreator = new ChefPizzaCreator(pizzaComposer, catalogue);
            theChefSystemVM = new ChefSystemVM(userSpace, theChefPizzaCreator);
        }
        #endregion 
        
        #region Manager
        ToppingAdministrator theToppingAdministrator;
        DoughAdministrator theDoughAdministrator;
        CashAdministrator theCashAdministrator;
        PizzaAdministrator thePizzaAdministrator;
        ClientAdministrator theClientAdministrator;
        ReportCreator theReportCreator;
        ManagerSystemVM theManagerSystemVM;
        public ManagerSystemVM ManagerSystemVM { get { return theManagerSystemVM; } }
        private void InitializeManagerSystem(StarDataDataContext db, 
            StockHandler stockHandler, Catalogue catalogue, UserSpace userSpace, OrderHistory orderHistory, CashRegister cashRegister,
            ToppingLister toppingLister, DoughLister doughLister, PizzaTemplateLister pizzaTemplateLister)
        {
            theToppingAdministrator = new ToppingAdministrator(db, stockHandler, toppingLister);
            theDoughAdministrator = new DoughAdministrator(db, stockHandler, doughLister);
            theCashAdministrator = new CashAdministrator(cashRegister);
            thePizzaAdministrator = new PizzaAdministrator(db, pizzaTemplateLister);
            theClientAdministrator = new ClientAdministrator(db, userSpace);
            theReportCreator = new ReportCreator(orderHistory, pizzaTemplateLister);

            theManagerSystemVM = new ManagerSystemVM(userSpace,
                theToppingAdministrator,
                theDoughAdministrator,
                theClientAdministrator,
                thePizzaAdministrator,
                theCashAdministrator,
                theReportCreator);
        }
        #endregion

        public Shell(string connectionString)
        {
            theModel = new ModelMain(connectionString);
            var m = theModel;

            InitializeUserSystem(
                m.UserSpace);

            InitializeCore(
                m.DB, m.UserSpace, m.IngredientResource, m.Catalogue);

            InitializeClientSystem(
                m.DB, m.UserSpace, m.OrderProcessor, m.Catalogue,
                thePizzaComposer, theDoughLister);

            InitializeChefSystem(
                m.Catalogue, m.UserSpace,
                thePizzaComposer);

            InitializeManagerSystem(
                m.DB, m.StockHandler, m.Catalogue, m.UserSpace, m.OrderHistory, m.CashRegister,
                theToppingLister, theDoughLister, thePizzaTemplateLister);
        }
        public void Start()
        {
            theUserAuthenticator.IsVisible = true;
        }
    }
}
